#include "evm_module.h"
#include <unistd.h>

#include <pthread.h>

#include "message_queue.h"

static bool s_eventbus_flag = false;

static struct message_queue *evm_queue = NULL;
static pthread_mutex_t mutex;


void* evm_module_msgqueue_create(int size, int len){
    struct message_queue *queue = evm_malloc(sizeof (struct message_queue));
    if(message_queue_init(queue, size, len) != 0){
        evm_print("msg init failed...\r\n");
        return NULL;
    }
    return queue;
}

int evm_module_msgqueue_destory(void *queue){
    message_queue_destroy((struct message_queue *)queue);
}

int evm_module_msg_put(const evm_event_msg_t *ptr, int timeout){
    pthread_mutex_lock(&mutex);
    void *msg = message_queue_message_alloc_blocking(evm_queue);
    if(msg == NULL){
         pthread_mutex_unlock(&mutex);
        return -1;
    }
    memcpy(msg, ptr, sizeof (evm_event_msg_t));
    message_queue_write(evm_queue, msg);
    pthread_mutex_unlock(&mutex);
    return 0;
}

int evm_module_msg_get(evm_event_msg_t *ptr, int timeout){
    pthread_mutex_lock(&mutex);
    int retry = (timeout*10) == 0 ? 1:0;
    while(retry--){
        void *msg = message_queue_tryread(evm_queue);
        if(msg == NULL){
            usleep(100);
            continue;
        }
        memcpy(ptr, msg, sizeof (evm_event_msg_t));
        message_queue_message_free(evm_queue, msg);
        pthread_mutex_unlock(&mutex);
        return 0;
    }
    pthread_mutex_unlock(&mutex);
    return -1;
}

evm_event_msg_t *evm_module_msg_create(void){
    evm_event_msg_t *msg = evm_malloc(sizeof(evm_event_msg_t));
    memset(msg, 0, sizeof (evm_event_msg_t));
    return msg;
}

void evm_module_msg_clear(evm_event_msg_t *msg){
    if(msg == NULL)
        return ;

    if(msg->data!=NULL){
        msg->free(msg->data);
    }
    memset(msg, 0, sizeof (evm_event_msg_t));
}

void evm_module_msg_destory(evm_event_msg_t *msg){
    if(msg == NULL)
        return ;
    evm_module_msg_clear(msg);
    evm_free(msg);
    msg = NULL;
}

int evm_module_eventbus_init(void){
    if(s_eventbus_flag == true)
        return 0;

    evm_queue = (struct message_queue *)evm_module_msgqueue_create(sizeof(evm_event_msg_t), 128);
    if(evm_queue == NULL)
        return -1;
    pthread_mutex_init(&mutex, NULL);

    s_eventbus_flag = true;

    return 0;
}

void evm_module_eventbus_destory(void){
    message_queue_destroy(evm_queue);
    pthread_mutex_destroy(&mutex);
    s_eventbus_flag = false;
}



